package com.example.his.api.front.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
//import cn.felord.payment.wechat.v3.WechatApiProvider;
import cn.dev33.satoken.stp.StpUtil;
import cn.felord.payment.wechat.v3.WechatApiProvider;
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import com.example.his.api.common.PageUtils;
import com.example.his.api.common.R;
import com.example.his.api.config.sa_token.StpCustomerUtil;
import com.example.his.api.front.controller.form.RefundForm;
import com.example.his.api.front.controller.form.SearchPaymentResultForm;
import com.example.his.api.front.controller.form.order.CreatePaymentForm;
import com.example.his.api.front.controller.form.order.SearchOrderByPageForm;
import com.example.his.api.front.service.OrderService;
import com.example.his.api.socket.WebSocketService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@RestController("FrontOrderController")
@RequestMapping("/front/order")
@Slf4j
public class OrderController {
  @Resource
  private OrderService orderService;
  
  //  @Resource
  //  private WechatApiProvider wechatApiProvider;
  
  @PostMapping("/createPayment")
  @SaCheckLogin(type = StpCustomerUtil.TYPE)
  public R createPayment(@RequestBody @Valid CreatePaymentForm form) {
    int customerId = StpCustomerUtil.getLoginIdAsInt();
    Map param = BeanUtil.beanToMap(form);
    param.put("customerId", customerId);
    HashMap map = orderService.createPayment(param);
    if(map == null) {
      //      当日不能下单
      return R.ok().put("illegal", true);
    } else {
      return R.ok().put("illegal", false).put("result", map);
    }
  }
  
  @SneakyThrows
  @PostMapping("/payMentCallback")
  public Map payMentCallback(@RequestHeader("Wechatpay-Serial") String serial, @RequestHeader("Wechatpay-Signature") String signature, @RequestHeader("Wechatpay-Timestamp") String timestamp, @RequestHeader("Wechatpay-Nonce") String nonce, HttpServletRequest request) {
    String body = request.getReader().lines().collect(Collectors.joining());
    //    对请求头进行验签，以确保时微信服务器的调用
    ResponseSignVerifyParams params = new ResponseSignVerifyParams();
    params.setWechatpaySerial(serial);
    params.setWechatpaySignature(signature);
    params.setWechatpayTimestamp(timestamp);
    params.setWechatpayNonce(nonce);
    params.setBody(body);
    //    return wechatApiProvider.callback("his-vue").transactionCallback(params, data -> {
    //      String transactionId = data.getTransactionId();
    //      String outTradeNo = data.getOutTradeNo();
    //      //      更新订单状态和付款单ID
    //      boolean bool = orderService.updatePayment(new HashMap() {{
    //        put("outTradeNo", outTradeNo);
    //        put("transactionId", transactionId);
    //      }});
    //      //  用websocket通知前端项目付款成功
    //      if(bool) {
    //        log.debug("付款成功,已更新订单状态");
    //        //        查询订单的customerid
    //        Integer customerId = orderService.searchCustomerId(outTradeNo);
    //        if(customerId == null) {
    //          log.error("付款成功,但无法查询到订单的customerid");
    //        } else {
    //          //          推送消息到前端
    //          JSONObject json = new JSONObject();
    //          json.set("result", true);
    //          WebSocketService.sendInfo(json.toString(), "customer_" + customerId.toString());
    //        }
    //      } else {
    //        log.error("订单付款成功，但是更新状态失败");
    //      }
    //    });
    return null;
  }
  
  @PostMapping("/searchPaymentResult")
  @SaCheckLogin(type = StpCustomerUtil.TYPE)
  public R serachPaymentResult(@Valid @RequestBody SearchPaymentResultForm form) {
    boolean b = orderService.searchPaymentResult(form.getOutTradeNo());
    return new R().ok().put("result", b);
  }
  
  @PostMapping("/searchByPage")
  @SaCheckLogin(type = StpCustomerUtil.TYPE)
  public R searchByPage(@RequestBody @Valid SearchOrderByPageForm form) {
    int page = form.getPage();
    int length = form.getLength();
    int start = (page - 1) * length;
    Map <String, Object> param = BeanUtil.beanToMap(form);
    param.put("start", start);
    int loginIdAsInt = StpCustomerUtil.getLoginIdAsInt();
    param.put("customerId", loginIdAsInt);
    
    PageUtils res = orderService.searchByPage(param);
    return R.ok().put("result", res);
  }
  
  @PostMapping("/refund")
  @SaCheckLogin(type = StpCustomerUtil.TYPE)
  public R refund(@Valid @RequestBody RefundForm form) {
    int customerId = StpCustomerUtil.getLoginIdAsInt();
    Map <String, Object> map = BeanUtil.beanToMap(form);
    map.put("customerId", customerId);
    boolean bool = orderService.refund(map);
    
    return R.ok().put("result", bool);
  }
  
  @PostMapping("/insert")
  @Transactional
  @SaCheckLogin(type = StpCustomerUtil.TYPE)
  public R insert(@Valid @RequestBody CreatePaymentForm form) {
    int customerId = StpCustomerUtil.getLoginIdAsInt();
    Map param = BeanUtil.beanToMap(form);
    param.put("customerId", customerId);
    int rows = orderService.insert(param);
    if(rows == 0) {
      return R.ok().put("result", false);
    } else {
      return R.ok().put("result", true);
    }
  }
  
  @SneakyThrows
  @PostMapping("/refundCallback")
  public Map refundCallback(@RequestHeader("Wechatpay-Serial") String serial, @RequestHeader("Wechatpay-Signature") String signature, @RequestHeader("Wechatpay-Timestamp") String timestamp, @RequestHeader("Wechatpay-Nonce") String nonce, HttpServletRequest request) {
    
    String body = request.getReader().lines().collect(Collectors.joining());
    //    验证数字签名，确保是微信服务器发送的通知消息
    ResponseSignVerifyParams params = new ResponseSignVerifyParams();
    params.setWechatpaySerial(serial);
    params.setWechatpaySignature(signature);
    params.setWechatpayNonce(nonce);
    params.setWechatpayTimestamp(timestamp);
    params.setBody(body);
    
    //    return wechatApiProvider.callback("his-vue").refundCallback(params, data -> {
    //      //      判断退款是否成功
    //      String status = data.getRefundStatus().toString();
    //      if("SUCCESS".equals(status)) {
    //        String outRefundNo = data.getOutRefundNo();
    //        //        将订单更新成已退款状态
    //        boolean bool = orderService.updateRefundStatus(outRefundNo);
    //        if(! bool) {
    //          log.error("更新订单状态失败");
    //        } else {
    //          log.debug("更新订单状态成功,退款单流水号为" + outRefundNo);
    //        }
    //      } else if("PROCESSING".equals(status)) {
    //        //        用户银行卡作废或者冻结，发送短信通知用户
    //      }
    //    });
    return null;
  }
}
